use actix_multipart::MultipartError;
use actix_web::{HttpResponse, ResponseError};
use serde_json::json;
use thiserror::Error;
use utoipa::ToSchema;

use crate::base::response::ApiResponse;

/// 返回错误枚举
#[derive(Error, Debug, ToSchema)]
pub enum AppError {
    /// 身份验证错误（code: 401）
    #[error("身份验证失败")]
    Unauthorized,

    /// 无效Token（code: 401）
    #[error("无效的Token")]
    InvalidToken,

    /// 缺少Token（code: 401）
    #[error("缺少Token或格式不正确")]
    MissingToken,

    /// 权限错误（code: 403）
    #[error("禁止：{0}")]
    Forbidden(String),

    /// 服务器内部错误（code: 500）
    #[error("服务器内部错误")]
    Internal,

    /// 运行时错误（code: 500）
    #[error("{0}")]
    Runtime(String),

    /// 无效请求（code: 400）
    #[error("错误请求: {0}")]
    BadRequest(String),

    /// 未找到（code: 404）
    #[error("未找到：{0}")]
    NotFound(String),

    /// 数据库错误（code: 500）
    #[error("SQL执行异常: {0}")]
    Database(String),

    /// 文件上传错误（code: 400）
    #[error("文件上传错误: {0}")]
    Multipart(String),
}

impl ResponseError for AppError {
    fn error_response(&self) -> HttpResponse {
        match self {
            AppError::Unauthorized => HttpResponse::Unauthorized()
                .json(json!({"error": "没有权限访问该资源"})),

            AppError::InvalidToken => HttpResponse::Unauthorized()
                .json(json!({"error": "TOKEN无效或已过期"})),

            AppError::MissingToken => HttpResponse::Unauthorized()
                .json(json!({"error": "TOKEN为空或格式不正确"})),

            AppError::Forbidden(reason) => HttpResponse::Forbidden()
                .json(json!({"error": reason})),

            AppError::Internal => HttpResponse::InternalServerError()
                .json(json!({"error": "内部服务器错误"})),

            AppError::Runtime(msg) => ApiResponse::error(msg.to_string()),

            // AppError::BadRequest(msg) => HttpResponse::BadRequest()
            //     .json(json!({"error": msg})),

            AppError::BadRequest(msg) => ApiResponse::error(msg.to_string()),

            AppError::NotFound(msg) => HttpResponse::NotFound()
                .json(json!({"error": msg})),

            AppError::Database(msg) => HttpResponse::InternalServerError()
                .json(json!({"error": format!("SQL执行异常: {}", msg)})),

            AppError::Multipart(msg) => HttpResponse::BadRequest()
                .json(json!({"error": msg})),
        }
    }
}

// 给 AppError 绑定业务错误码
// impl AppError {
//     /// 获取错误对应的业务码
//     pub fn code(&self) -> i32 {
//         match self {
//             AppError::Unauthorized | AppError::InvalidToken | AppError::MissingToken => 401,
//             AppError::Forbidden(_) => 403,
//             AppError::BadRequest(_) | AppError::Multipart(_) => 400,
//             AppError::NotFound(_) => 404,
//             AppError::Internal | AppError::Runtime(_) | AppError::Database(_) => 500,
//         }
//     }

//     /// 生成统一的 200 响应（JSON 格式）
//     pub fn to_api_response(&self) -> HttpResponse {
//         ApiResponse::error(
//             self.code(),
//             self.to_string(),
//         )
//     }
// }

impl From<MultipartError> for AppError {
    fn from(err: MultipartError) -> Self {
        AppError::Multipart(err.to_string())
    }
}

// sqlx 错误的转换
impl From<sqlx::Error> for AppError {
    fn from(err: sqlx::Error) -> Self {
        AppError::Database(err.to_string())
    }
}